/*
 *  src/mm/mm_free.c
 *
 *  Harry Wei <harryxiyou@gmail.com> (C) 2011
 */
#include <glib.h>
#include <stdio.h>

#include "mm.h"

int mm_free(struct mm_ctrl *ctrl, uint32_t start_addr, 
		uint32_t size, const char *process_name)
{//TODO free mem between start_addr and start_addr + size - 1
	g_message("enter func %s", __func__);
	if (NULL == ctrl || (size > ctrl->max_size) ||
		(start_addr < ctrl->start_addr) || (start_addr > ctrl->end_addr)) {
		g_message("%s -- ctrl is null || parameter error!", __func__);
		return -1;
	}
	int ret = 0;
	struct allocate_section *tmp1 = NULL;
	struct allocate_section *tmp2 = NULL;
	tmp2 = ctrl->allocate_head;
	tmp1 = ctrl->allocate_head->next;
	if (0 == g_strcmp0(tmp2->process_name, process_name)) {
		g_message("%s -- find it, name is %s", __func__, tmp2->process_name);
		g_message("%s -- pid is %d, size is %d, start_addr is %d, end_addr is %d,process_name is %s", 
				__func__, tmp2->pid, tmp2->size,tmp2->start_addr, 
						tmp2->end_addr, tmp2->process_name);
		tmp2->next = NULL;
		ctrl->allocate_head = tmp1;
		ctrl->free_size += tmp2->size;
		ctrl->allocate_size -= tmp2->size;
		ctrl->process_nums -= 1;
		if (tmp2 == ctrl->cur_allocate_handler) {
			ctrl->cur_allocate_handler = NULL;
		}
		struct free_section *free = (struct free_section *)g_malloc0(sizeof(struct free_section));
		if (NULL == free) {
			g_message("%s -- allocate error!", __func__);
			ret = -1;
			goto out;
		}
		free->size = tmp2->size;
		free->start_addr = tmp2->start_addr;
		free->end_addr = tmp2->end_addr;
		if (NULL == ctrl->free_head) {
			ctrl->free_head = free;
		} else {
			ctrl->cur_free_handler->next = free;
		}
		free->next = NULL;
		ctrl->cur_free_handler = free;
		g_free(tmp2);
		goto out;
	}
	while (1) {
		if (0 == g_strcmp0(tmp1->process_name, process_name)) {
			g_message("%s -- find it, name is %s", __func__, tmp1->process_name);
			tmp2->next = tmp1->next;
//			ctrl->allocate_head = tmp1;
			ctrl->free_size += tmp1->size;
			ctrl->allocate_size -= tmp1->size;
			ctrl->process_nums -= 1;
			if (tmp1 == ctrl->cur_allocate_handler) {
				ctrl->cur_allocate_handler = tmp2;
			}
			struct free_section *free = (struct free_section *)g_malloc0(sizeof(struct free_section));
			if (NULL == free) {
				g_message("%s -- allocate error!", __func__);
				ret = -1;
				goto out;
			}
			free->size = tmp1->size;
			free->start_addr = tmp1->start_addr;
			free->end_addr = tmp1->end_addr;
			if (NULL == ctrl->free_head) {
				ctrl->free_head = free;
			} else {
				ctrl->cur_free_handler->next = free;
			}
			free->next = NULL;
			ctrl->cur_free_handler = free;
			g_free(tmp1);
			goto out;
		}
		if (NULL == tmp1->next) {
			g_message("%s -- no this process %s", __func__, process_name);
			goto out;
		}
		tmp1 = tmp1->next;
		tmp2 = tmp2->next;
	}
out:
	g_message("leave func %s", __func__);
	return ret;
}
